<script setup lang="ts">
import { reactive, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useEmitt } from '@/hooks/web/useEmitt'
import { ElMessage } from 'element-plus'
import { Check, Close, Delete } from '@element-plus/icons-vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useLocaleStore } from '@/store/modules/locale'
import { selectModule, saveDataSource, getDataSource, checkDsRepeat } from '@/api/develop'

defineOptions({
  name: 'DataSourceEdit'
})

const localeStore = useLocaleStore()

const { t } = useI18n()
const { emitter } = useEmitt()
const formRef = ref()
const { currentRoute } = useRouter()

const defaultDetail = [
  { prop: 'url', value: 'jdbc:mysql://localhost:3306/dbName' },
  { prop: 'username', value: '' },
  { prop: 'password', value: '' },
  { prop: 'maxActive', value: '8' }
]

const state = reactive({
  // 表单数据
  formData: {
    dsId: null,
    identifier: '',
    moduleId: '',
    dsName: '',
    dbType: '',
    isPublic: 1,
    remark: '',
    detail: '',
    status: 1,
    seq: 1
  },
  details: [...defaultDetail],
  // 校验规则
  formRules: {
    identifier: [
      {
        required: true,
        message: t('orderNo.identifier') + t('common.notEmpty'),
        trigger: ['blur']
      }
    ],
    dsName: [
      {
        required: true,
        message: t('datasource.name') + t('common.notEmpty'),
        trigger: ['blur']
      }
    ],
    status: { required: true },
    isPublic: { required: true },
    moduleId: [
      {
        required: true,
        message: t('orderNo.module') + t('common.notEmpty'),
        trigger: ['blur', 'change']
      }
    ]
  },
  modNameField: 'moduleName',
  moduleList: [{}],
  propList: [
    //{ prop: 'url' },    { prop: 'username' },    { prop: 'password' },    { prop: 'maxActive' },
    { prop: 'initialSize' },
    { prop: 'minIdle' },
    { prop: 'maxWait' },
    { prop: 'poolPreparedStatements' },
    { prop: 'maxPoolPreparedStatementPerConnectionSize' },
    { prop: 'validationQuery' },
    { prop: 'validationQueryTimeout' },
    { prop: 'testOnBorrow' },
    { prop: 'testOnReturn' },
    { prop: 'testWhileIdle' },
    { prop: 'keepAlive' },
    { prop: 'driverClassName' },
    { prop: 'timeBetweenEvictionRunsMillis' },
    { prop: 'minEvictableIdleTimeMillis' },
    { prop: 'connectionInitSqls' },
    { prop: 'exceptionSorter' }
  ],
  loading: false
})

//加载事件
onMounted(async () => {
  state.moduleList = await selectModule()
  //当前语言
  const curLang = localeStore.getCurrentLocale.lang
  if (curLang == 'en') {
    state.modNameField = 'enName'
  } else if (curLang == 'zh_HK') {
    state.modNameField = 'hkName'
  }
  init()
})

//是否是默认属性
const isDefaultProp = (text) => {
  if (!text || text.length == 0) {
    return false
  }
  for (const prop of defaultDetail) {
    const row = prop as any
    if (row.prop == text) {
      return true
    }
  }
  return false
}

//删除属性
const deleteRow = (index, row) => {
  if (isDefaultProp(row.prop)) {
    ElMessage.warning(t('datasource.mustHave'))
    return
  }
  state.details.splice(index, 1)
}
//新增属性
const addRow = () => {
  const row = {
    prop: '',
    value: ''
  }
  state.details.push(row)
}

// 保存表单
const save = () => {
  formRef.value.validate(async (vaild) => {
    if (!vaild) {
      return
    }
    let form = Object.assign({}, state.formData)
    //校验明细记录
    if (state.details && state.details.length > 0) {
      for (const row of state.details) {
        if (row.prop == '' || row.value == '') {
          ElMessage.warning(t('dataDict.rowCheck'))
          return
        }
        const prop = row.prop
        //检查整型字段
        if (
          prop == 'initialSize' ||
          prop == 'maxActive' ||
          prop == 'minIdle' ||
          prop == 'maxWait' ||
          prop == 'maxPoolPreparedStatementPerConnectionSize' ||
          prop == 'validationQueryTimeout' ||
          prop == 'timeBetweenEvictionRunsMillis' ||
          prop == 'minEvictableIdleTimeMillis'
        ) {
          const number = parseInt(row.value)
          if (isNaN(number) || number < 0) {
            ElMessage.error(prop + ' ' + t('datasource.beNumber'))
            return
          }
          if (prop == 'maxWait' && number > 8) {
            row.value = '8'
          }
        }
        if (
          prop == 'poolPreparedStatements' ||
          prop == 'testOnBorrow' ||
          prop == 'testOnReturn' ||
          prop == 'testWhileIdle' ||
          prop == 'keepAlive'
        ) {
          if (row.value != 'true' && row.value != 'false') {
            ElMessage.error(prop + ' ' + t('datasource.beBoolean'))
            return
          }
        }
      }
    }
    if (checkDetails()) {
      return
    }
    form.detail = JSON.stringify(state.details)
    state.loading = true
    let type = 'add'
    if (form.dsId) {
      type = 'edit'
    }
    await saveDataSource(form).then((res) => {
      state.loading = false
      const result = res as any
      //保存成功
      if (result.success) {
        //刷新列表
        emitter.emit('refreshDatasourceList', type)
        goBack()
      }
    })
  })
}

//检查子表属性列是否有重复
const checkDetails = () => {
  if (state.details.length == 0) {
    return false
  }
  const len = state.details.length
  const vals = new Set()
  for (const detail of state.details) {
    const row = detail as any
    vals.add(row.prop)
  }
  if (vals.size != len) {
    ElMessage.error(t('datasource.propRepeat'))
    return true
  }
  return false
}

//检查标识符是否重复
const checkKey = (event) => {
  const key = event.target.value
  if (!key || key.length == 0) {
    return
  }
  checkDsRepeat(key, state.formData.dsId)
}
// 返回列表
const goBack = () => {
  emitter.emit('closeTag', {
    closePath: currentRoute.value.path,
    backPath: '/Develop/DataSource'
  })
}

//渲染页面的接口
const init = async () => {
  const id = currentRoute.value.query.id as string
  state.details = [...defaultDetail]
  //修改
  if (id) {
    const data = (await getDataSource(id)) as any
    state.formData = data.data
    const detail = state.formData.detail
    if (detail && detail.length > 0 && detail != '[]') {
      state.details = JSON.parse(detail)
    }
  } else {
    const moduleId = currentRoute.value.query.moduleId as string
    if (moduleId) {
      state.formData.moduleId = moduleId
    }
  }
}
</script>

<template>
  <div>
    <!-- 卡片表頭 -->
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>{{ $t('datasource.title') }}</span>
        </div>
      </template>
      <el-form
        ref="formRef"
        :model="state.formData"
        :rules="state.formRules"
        class="demo-form-inline"
        label-position="left"
        label-width="150px"
        style="padding-top: 10px"
      >
        <el-row :gutter="40">
          <el-col :xs="24" :sm="24" :md="12">
            <el-form-item :label="$t('orderNo.module')" prop="moduleId">
              <el-select
                v-model="state.formData.moduleId"
                :placeholder="$t('common.selectText')"
                size="default"
              >
                <el-option
                  v-for="item in state.moduleList"
                  :key="item.moduleId"
                  :label="item[state.modNameField]"
                  :value="item.moduleId"
                />
              </el-select>
            </el-form-item>
            <el-form-item :label="$t('datasource.name')" prop="dsName">
              <el-input
                v-model="state.formData.dsName"
                :placeholder="$t('common.inputText') + $t('datasource.name')"
                maxlength="50"
                show-word-limit
              />
            </el-form-item>
            <el-row>
              <el-col :span="8">
                <el-form-item :label="$t('datasource.isPublic')" prop="isPublic">
                  <el-switch
                    v-model.number="state.formData.isPublic"
                    :active-value="1"
                    :inactive-value="0"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8" :offset="6">
                <el-form-item :label="$t('common.status')" prop="status" label-width="80px">
                  <el-switch
                    v-model.number="state.formData.status"
                    :active-value="1"
                    :inactive-value="0"
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </el-col>
          <el-col :xs="24" :sm="24" :md="12">
            <el-form-item :label="$t('orderNo.identifier')" prop="identifier">
              <el-input
                v-model="state.formData.identifier"
                :placeholder="$t('common.inputText') + $t('orderNo.identifier')"
                maxlength="50"
                show-word-limit
                @blur="checkKey($event)"
              />
            </el-form-item>
            <el-form-item :label="$t('common.remark')" prop="remark">
              <el-input
                v-model="state.formData.remark"
                :placeholder="$t('common.inputText') + $t('common.remark')"
                maxlength="255"
                show-word-limit
              />
            </el-form-item>
            <el-form-item :label="$t('datasource.dbType')" prop="dbType">
              <el-input
                v-model="state.formData.dbType"
                :placeholder="$t('datasource.autoKnow')"
                disabled
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div style="margin: 10px 0">
        <el-row>
          <el-col :span="20"
            ><Icon icon="ic:outline-tips-and-updates" />&nbsp;{{ $t('datasource.propHelp') }}：<a
              target="_blank"
              style="color: darkblue; text-decoration: underline"
              href="https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8"
              >https://github.com/alibaba/druid/wiki/</a
            ></el-col
          >
          <el-col :span="4" style="text-align: right">
            <el-button type="success" size="small" plain @click="addRow()">
              <Icon icon="material-symbols:add-circle-rounded" />
              <span>{{ t('datasource.add') }}</span></el-button
            ></el-col
          >
        </el-row>
      </div>
      <div style="width: 100%">
        <el-table
          :data="state.details"
          tooltip-effect="light"
          style="width: 100%; border-color: #a0cfff; font-size: 12px"
          stripe
          default-expand-all
          border
          :header-cell-style="{
            background: 'var(--el-color-primary-light-9)',
            color: '#409eff'
          }"
        >
          <el-table-column type="index" min-width="60">
            <template #header>
              <div style="margin-bottom: -10px">
                <Icon
                  icon="ant-design:field-number-outlined"
                  size="24"
                  :title="$t('common.number')"
              /></div>
            </template>
          </el-table-column>
          <el-table-column prop="prop" :label="$t('datasource.prop')" width="330">
            <template #default="scope">
              <el-select
                v-model="scope.row.prop"
                :placeholder="$t('common.selectText')"
                size="default"
                class="inputRequired"
                :disabled="isDefaultProp(scope.row.prop)"
              >
                <el-option
                  v-for="item in state.propList"
                  :key="item.prop"
                  :label="item.prop"
                  :value="item.prop"
                />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column prop="value" :label="$t('datasource.value')" min-width="200">
            <template #default="scope">
              <el-input v-model="scope.row.value" class="inputRequired" />
            </template>
          </el-table-column>
          <el-table-column
            prop="op"
            align="center"
            fixed="right"
            :label="$t('common.operation')"
            width="80"
          >
            <template #default="scope">
              <el-button
                type="danger"
                size="small"
                plain
                circle
                :title="$t('common.delete')"
                v-if="!isDefaultProp(scope.row.prop)"
                @click="deleteRow(scope.$index, scope.row)"
              >
                <el-icon>
                  <Delete />
                </el-icon>
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="detailFooter">
        <el-button type="primary" plain @click="save" :loading="state.loading">
          <el-icon><Check /></el-icon>&nbsp;{{ $t('common.save') }}
        </el-button>
        <el-button type="info" plain @click="goBack">
          <el-icon><Close /></el-icon>&nbsp;{{ $t('common.giveUp') }}
        </el-button>
      </div>
    </el-card>
  </div>
</template>
<style lang="less" scoped>
.box-card {
  .card-header {
    font-size: 16px;
    letter-spacing: 1px;
  }
  :deep(.el-input) {
    font-size: 12px;
  }
  :deep(.el-textarea__inner) {
    height: 85px;
    font-size: 12px;
  }
}
:deep(.el-input__inner) {
  &::placeholder {
    font-size: 12px;
  }
}
.el-select-dropdown__item {
  font-size: 12px;
}
.required {
  color: red;
}
.inputRequired {
  width: 98%;
}
</style>
